/*
 * @(#)ConfigDOMBuilderTestCase.java $version 2010. 8. 11
 *
 * Copyright 2007-2010 NHN Corp. All rights Reserved. 
 * NHN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package com.nhncorp.usf.core.config;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletContext;

import junit.framework.Assert;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.mock.web.MockServletContext;

import com.nhncorp.lucy.common.config.model.ApplicationInfo;
import com.nhncorp.lucy.common.container.SpringBeanFactory;
import com.nhncorp.usf.core.config.runtime.Action;
import com.nhncorp.usf.core.config.runtime.BusinessObject;
import com.nhncorp.usf.core.config.runtime.Method;
import com.nhncorp.usf.core.config.runtime.PageInfo;
import com.nhncorp.usf.core.config.runtime.ParameterInfo;
import com.nhncorp.usf.core.config.runtime.ResultPageInfo;
import com.nhncorp.usf.core.config.runtime.ResultPageInfos;
import com.nhncorp.usf.core.config.runtime.ScriptEngineGlobals;
import com.nhncorp.usf.core.config.runtime.ScriptInfo;
import com.nhncorp.usf.core.exception.DefaultExceptionHandler;
import com.nhncorp.usf.core.exception.ExceptionHandler;
import com.nhncorp.usf.core.invoker.ConnectorHolder;
import com.nhncorp.usf.core.invoker.InvocationConnectorManager;
import com.nhncorp.usf.core.invoker.Invoker;
import com.nhncorp.usf.core.invoker.SpringInvoker;
import com.nhncorp.usf.core.service.DefaultServiceExecutor;
import com.nhncorp.usf.core.service.ServiceExecutor;
import com.nhncorp.usf.core.servlet.ServletContextHolder;
import com.nhncorp.usf.core.util.ScriptUtil;

/**
 * @author Web Platform Development Team
 */
public class ConfigDOMBuilderTestCase {
    private static ServiceExecutor serviceExecutor = new DefaultServiceExecutor();

    private static PageInfo pageInfo;

    private static Action actionInfo;
    private static Action commonActionInfo;

    @BeforeClass
    public static void beforeClass() throws Exception {
        // pageInfo
        pageInfo = new PageInfo("dummy");
        ResultPageInfo defaultResultPageInfo = new ResultPageInfo(ResultPageInfo.DISPATCHER_TYPE.mock, "mock script source");
        ResultPageInfos resultPageInfos = new ResultPageInfos();
        resultPageInfos.setDefaultResultPageInfo(defaultResultPageInfo);
        pageInfo.setGlobalSuccessResultInfo(resultPageInfos);
        pageInfo.setGlobalFailureResultInfo(resultPageInfos);

        // actionInfo
        actionInfo = new Action("testAction");
        pageInfo.addActionInfo("testAction", actionInfo);

        commonActionInfo = new Action("commonAction");
        pageInfo.setCommonAction(commonActionInfo);

        ApplicationInfo.setFileEncoding("utf-8");
        Invoker invoker = new SpringInvoker();
        ConnectorHolder connectorHolder = new ConnectorHolder(invoker);

        SpringBeanFactory.init(new ClassPathXmlApplicationContext("applicationContext-bo.xml"));
        ExceptionHandler exceptionHandler = new DefaultExceptionHandler();
        serviceExecutor.setInvoker(invoker);
        serviceExecutor.setExceptionHandler(exceptionHandler);

        InvocationConnectorManager.getInstance().putInvoker(
                "localSpring",
                connectorHolder
        );

        ConnectorInfos.getInstance().setDefaultConnector("localSpring");
        ServletContext servletContext = new MockServletContext();
        ServletContextHolder.set(servletContext);
        String scriptDirPath = servletContext.getRealPath("/scripts");
        ServletContextHolder.setContextRealPath(scriptDirPath);
        ScriptUtil.loadJSFile(scriptDirPath);
    }

    @AfterClass
    public static void destroy() throws Exception {
        SpringBeanFactory.clear();
        InvocationConnectorManager.getInstance().putInvoker("localSpring", (Invoker) null);
    }

    @SuppressWarnings("unchecked")
	@Test
    public void conditionScriptMethodServiceExecuteWithJS() throws Exception {
        Action actionInfo = new Action("dummy_action");
        // action-service
        BusinessObject businessObjectInfo = new BusinessObject("com.nhncorp.usf.core.service.mock.PersonBO", false);
        Method methodInfo = new Method("getPerson", "person");
        methodInfo.addParameterInfo(new ParameterInfo("name", null, "Gildong,Hong"));
        methodInfo.addParameterInfo(new ParameterInfo("age", null, "10"));
        businessObjectInfo.addMethodInfo(methodInfo);

        ScriptInfo scriptInfo = new ScriptInfo(ScriptEngineGlobals.JAVASCRIPT_SCRIPT_ENGINE_NAME, "replaceValue");
        scriptInfo.setParams("Hi, my name is choco");
        scriptInfo.setReturnId("message");
        actionInfo.setResultCommonScriptInfo(scriptInfo);
        Assert.assertEquals(scriptInfo.getParams(), "Hi, my name is choco");
        Assert.assertEquals(scriptInfo.getReturnId(), "message");

        actionInfo.addBusinessObjectInfo(businessObjectInfo);

        Map<String, Object> dataMap = new HashMap<String, Object>();
        ServiceExecutor.RESULT_STATUS resultStatus = serviceExecutor.execute(actionInfo, dataMap);

        Map resultMap = (Map) dataMap.get("person");
        Assert.assertEquals(resultStatus, ServiceExecutor.RESULT_STATUS.success);
        Assert.assertEquals(resultMap.get("name"), "Gildong,Hong");
        Assert.assertEquals(resultMap.get("age"), Integer.valueOf(10));        // age 는 10 으로 parameter 값 수정

        ScriptUtil.processControlScript(ServletContextHolder.getContextRealPath(), actionInfo.getResultCommonScriptInfo(), dataMap);
        Assert.assertEquals(dataMap.get("message"), "Hi, my name is nhn");
    }

    @Test
    public void pageInfoTest() throws Exception {
        PageInfo pageInfo = new PageInfo("dummy");
        long currentTime = System.currentTimeMillis();
        pageInfo.setCreatedTime(currentTime);
        pageInfo.addActionInfo("testAction", actionInfo);
        pageInfo.setCommonAction(commonActionInfo);
        ScriptInfo scriptInfo = new ScriptInfo(ScriptEngineGlobals.JAVASCRIPT_SCRIPT_ENGINE_NAME, "replaceValue");
        scriptInfo.setParams("Hi, my name is choco");
        scriptInfo.setReturnId("message");
        pageInfo.setPageCommonScriptInfo(scriptInfo);
        pageInfo.addParent(pageInfo);

        Assert.assertEquals(pageInfo.getId(), "dummy");
        Assert.assertEquals(pageInfo.getCommonAction().getId(), "commonAction");
        Assert.assertEquals(pageInfo.getActionInfos().size(), 1);
        Assert.assertTrue(pageInfo.getActionKeys().contains("testAction"));
        Assert.assertEquals(pageInfo.getCreatedTime(), currentTime);
        Assert.assertEquals(pageInfo.getPageCommonScriptInfo().getReturnId(), "message");
    }

    @Test
    public void parentPageInfoErrorTest() throws Exception {
        try {
            pageInfo.addParent(null);
        } catch (Throwable t) {
            Assert.assertEquals("Parent PageInfo must not be null", t.getMessage());
        }
    }
}
